import axios, {AxiosRequestConfig} from 'axios';
import {API_BASE} from '@configs';

// 定义接口
interface PendingType {
    url?: string;
    method?: string;
    params: any;
    data: any;
    cancel: Function;
}

// 取消重复请求
const pending: Array<PendingType> = [];
const CancelToken = axios.CancelToken;

// axios 实例
const service = axios.create({
    baseURL: API_BASE,
    timeout: 16000,
    responseType: 'json',
});

// 移除重复请求
const removePending = (config: AxiosRequestConfig) => {
    for (let i = 0; i < pending.length; i++) {
        const list: PendingType = pending[i];
        // 当前请求在数组中存在时执行函数体
        if (
            list.url === config.url &&
            list.method === config.method &&
            JSON.stringify(list.params) === JSON.stringify(config.params) &&
            JSON.stringify(list.data) === JSON.stringify(config.data)
        ) {
            // 执行取消操作
            list.cancel('操作太频繁，请稍后再试');
            // 从数组中移除记录
            pending.splice(i, 1);
        }
    }
};

// 添加请求拦截器
service.interceptors.request.use(
    (request) => {
        removePending(request);
        request.cancelToken = new CancelToken((c) => {
            pending.push({
                url: request.url,
                method: request.method,
                params: request.params,
                data: request.data,
                cancel: c,
            });
        });
        return request;
    },
    (error) => {
        return Promise.reject(error);
    },
);

// 添加响应拦截器
service.interceptors.response.use(
    (response): any => {
        removePending(response.config);
        return Promise.resolve(response);
    },
    (error) => {
        const response = error.response;
        if (response && response.data && response.data.result != undefined) {
            error.data = response.data;
            return Promise.reject(error);
        }
        error.data = axios.isCancel(error) ?
            {result: 99999, message: '请求频繁，请稍后再试'} :
            {result: 500, message: '接口未响应'};
        return Promise.reject(error);
    },
);

export default service;
